package zerdlib.events.containers;

import java.util.AbstractSequentialList;
import java.util.EventObject;

import zerdlib.events.DefaultListenable;
import zerdlib.events.GenericListenable;
import zerdlib.events.GenericListener;


public abstract class AbstractListenableSequentialList<E> extends AbstractSequentialList<E> implements ListenableList<E>, GenericListenable {
	protected DefaultListenable listenableManager = new DefaultListenable();
	@Override
	public void addListener(GenericListener toAddListener) {
		listenableManager.addListener(toAddListener);
	}

	@Override
	public void removeListener(GenericListener toRemoveListener) {
		listenableManager.removeListener(toRemoveListener);
	}

	@Override
	public void removeAllListener(GenericListener toRemoveListener) {
		listenableManager.removeAllListener(toRemoveListener);
	}

	@Override
	public void suspendEvents() {
		listenableManager.suspendEvents();
	}

	@Override
	public void resumeEvents() {
		listenableManager.resumeEvents();
	}

	public void fireEvent(EventObject ev) {
		listenableManager.fireEvent(ev);
	}
	
	
	
	
	protected GenericListener elementChangeListener = new GenericListener() {
		@SuppressWarnings("unchecked")
		@Override
		public void onEvent(EventObject ev) {
			onElementChange((E)ev.getSource());
		}
	};
	
	protected abstract void onElementChange(E e);

	
	
	
	protected void internalAdd(E e, int index) {
		if(e instanceof GenericListenable)
			((GenericListenable)e).addListener(elementChangeListener);
		fireEvent(new ListChangeEvent(this, ListChangeEvent.ELEMENT_ADDED, e, index));
	}
	
	protected void internalRemove(E e, int index) {
		if(e instanceof GenericListenable)
			((GenericListenable)e).removeListener(elementChangeListener);
		fireEvent(new ListChangeEvent(this, ListChangeEvent.ELEMENT_REMOVED, e, index));
	}
	
	protected void internalChange(E e, int index) {
		fireEvent(new ListChangeEvent(this, ListChangeEvent.ELEMENT_CHANGED, e, index));
	}
	
	protected void internalReplace(E old, E e, int index) {
		if(old instanceof GenericListenable)
			((GenericListenable)old).removeListener(elementChangeListener);
		if(e instanceof GenericListenable)
			((GenericListenable)e).addListener(elementChangeListener);
		fireEvent(new ListChangeEvent(this, ListChangeEvent.ELEMENT_CHANGED, e, index));
	}
}
